﻿using Fvs_Service.Log;
using Fvs_Service.Net;
using Fvs_Service.Protocol;
using Microsoft.Extensions.Configuration;

namespace Fvs_Service
{
    public class FvsMaid:ProtocolMaid
    {
        private int _routerPort;
        private int _noticePort;
        private int _minLampPort;
        private int _maxLampPort;
        private int _minRelayPort;
        private int _maxRelayPort;

        public override void Start()
        {
            var _config = new ConfigurationBuilder()
                .AddJsonFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"))
                .Build();
            //转发
            _routerPort = _config.GetValue("RouterPort", 7771);
            //通知
            _noticePort = _config.GetValue("NoticePort", 7772);

            //雾灯
            _minLampPort = _config.GetValue("MinLampPort", 60000);
            _maxLampPort = _config.GetValue("MaxLampPort", 60002);
            //继电器
            _minRelayPort = _config.GetValue("MinRelayPort", 60003);
            _maxRelayPort = _config.GetValue("MaxRelayPort", 60009);


            SocketChannel routerChannel =AddListenEndPoint(new ProtocolHandler(), _routerPort);
            routerChannel.Received += ProtocolReceiveHandler;
            AddListenEndPoint(new ProtocolHandler(), _noticePort);

            for (int i = _minLampPort; i <= _maxLampPort; ++i)
            {
                SocketChannel channel = AddListenEndPoint(new LampHandler(), i);
                channel.Received += NoticeReceiveHandler;
            }

            for (int i = _minRelayPort; i <= _maxRelayPort; ++i)
            {
                AddListenEndPoint(new RelayHandler(), i);
            }

            Task.Run(SetTags);
            base.Start();
        }

        private void NoticeReceiveHandler(object sender, ReceivedEventArgs e)
        {
            if (e.ProtocolId == 0x06
                || e.ProtocolId == 0x08
                || e.ProtocolId == 0x0a
                || e.ProtocolId == 0x0c
                || e.ProtocolId == 0x0e
                || e.ProtocolId == 0x0a)
            {
                Notice notice = new Notice
                {
                    Buffer = e.Buffer.ToArray(),
                    RemoteIp = BitConverter.ToUInt32(e.Channel.LocalEndPoint.Address.GetAddressBytes(), 0),
                    RemotePort = Convert.ToUInt16(e.Channel.LocalEndPoint.Port)
                };
                Broadcast(_noticePort.ToString(), Protocol.Protocol.Request(notice).Item1);
            }
            else if(e.ProtocolId==0x02)
            {
                e.Buffer[0] = 0x81;
                e.Channel.Send(null, e.Buffer);
            }
        }

        private void SetTags()
        {
            while(true)
            {
                foreach (var socket in _sockets)
                {
                    if (socket.Value.Type == SocketType.Accept)
                    {
                        int port = socket.Value.LocalEndPoint.Port;
                        if (port >= _minLampPort && port <= _maxLampPort)
                        {
                            if (socket.Value.Tag == port.ToString())
                            {
                                List<byte> buffer = new List<byte>
                                {
                                    0x81,
                                    0x7f,
                                    0x11,
                                    0xff
                                };
                                List<byte> receiveBuffer = new List<byte>();
                                if (socket.Value.Send(null, buffer, args => args.ProtocolId == 0x11, null, receiveBuffer) ==
                                    SocketResult.Success)
                                {
                                    socket.Value.Tag = string.Format($"{port}_{receiveBuffer[1]}");
                                    socket.Value.SetLogger($"Lamp_{socket.Value.Tag}");
                                    LogPool.LogInformation(LogEvents.Socket, $"tag {socket.Value.Socket.Handle} {socket.Value.Tag}");
                                }
                            }
                        }
                    }
                }
                Thread.Sleep(5*1000);
            } 
        }
    }
}
